学习node.JS前我们需要提前了解的前置知识(三) 您所在的位置:网站首页 node 引入js 学习node.JS前我们需要提前了解的前置知识(三)

学习node.JS前我们需要提前了解的前置知识(三)

2022-12-20 10:08| 来源: 网络整理| 查看: 265

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第21天,点击查看活动详情

三、模块/包 与 CommonJS 1、模块/包分类

Node.js 有三类模块,即内置的模块、第三方的模块、自定义的模块。

1.1 内置的模块

Node.js 内置模块又叫核心模块,Node.js安装完成可直接使用。如:

const path = require('path') var extname = path.extname('index.html') console.log(extname) 复制代码 1.2 第三方的Node.js模块

第三方的Node.js模块指的是为了实现某些功能,发布的npmjs.org上的模块,按照一定的开源协议供社群使用。如:

npm install chalk 复制代码 const chalk = require('chalk') console.log(chalk.blue('Hello world!')) 复制代码 1.3 自定义的Node.js模块

自定义的Node.js模块,也叫文件模块,是我们自己写的供自己使用的模块。同时,这类模块发布到npmjs.org上就成了开源的第三方模块。

自定义模块是在运行时动态加载,需要完整的路径分析、文件定位、编译执行过程、速度相比核心模块稍微慢一些,但是用的非常多。

1.3.1 模块定义、接口暴露和引用接口

我们可以把公共的功能 抽离成为一个单独的 js 文件 作为一个模块,默认情况下面这个模块里面的方法或者属性,外面是没法访问的。如果要让外部可以访问模块里面的方法或者属性,就必须在模块里面通过 exports 或者module.exports暴露属性或者方法。

m1.js:

const name = 'zayyo' const sayName = () => { console.log(name) } console.log('module 1') // 接口暴露方法一: module.exports = { say: sayName } // 接口暴露方法二: exports.say = sayName // 错误! exports = { say: sayName } 复制代码

main.js:

const m1 = require('./m1') m1.say() 复制代码 1.3.2 模块的循环引用

由于 exports 使用方式方式不对,会在两个不同 js 循环引用的情况下,导致其中一个 js 无法获取另外一个 js 的方法,从而导致执行报错。如:

a.js exports.done = false const b = require('./b.js') console.log('in a, b.done = %j', b.done) exports.done = true console.log('a done') 复制代码 b.js console.log('b starting') exports.done = false const a = require('./a.js') console.log('in b, a.done = %j', a.done) exports.done = true console.log('b done') 复制代码 main.js console.log('main starting') const a = require('./a.js') const b = require('./b.js') console.log('in main, a.done = %j, b.done = %j', a.done, b.done) 复制代码

main.js 首先会 load a.js, 此时执行到const b = require('./b.js');的时候,程序会转去loadb.js, 在b.js中执行到const a = require('./a.js'); 为了防止无限循环,将a.jsexports的未完成副本返回到b.js模块。然后b.js完成加载,并将其导出对象提供给a.js模块。

我们知道nodeJs的对每个js文件进行了一层包装称为module,module中有一个属性exports,当调用require('a.js')的时候其实返回的是module.exports对象,module.exports初始化为一个{}空的object,所以在上面的例子中,执行到b.js中const a = require('./a.js');时不会load新的a module, 而是将已经load但是还未完成的a module的exports属性返回给b module,所以b.js拿到的是a module的exports对象,即:{done:false}, 虽然在a.js中exports.done被修改成了true,但是由于此时a.js未load完成,所以在b.js输出的a module的属性done为false,而在main.js中输出的a module的属性done为true. Nodejs通过上面这种返回未完成exports对象来解决循环引用的问题。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有